package com.xiaolun.readWriteLock;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * 1、缓存
 */
class MyCache {
	private volatile Map<String, Object> map = new HashMap();
	private ReadWriteLock readWriteLock = new ReentrantReadWriteLock();

	public void put(String key, Object value) {
		readWriteLock.writeLock().lock();
		try {
			TimeUnit.SECONDS.sleep(1);
			System.out.println(Thread.currentThread().getName() + "\t写入数据" + key);
			map.put(key, value);
			System.out.println(Thread.currentThread().getName() + "\t写入完成");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			readWriteLock.writeLock().unlock();
		}
	}

	public void get(String key) {
		readWriteLock.readLock().lock();
		try {
			TimeUnit.SECONDS.sleep(1);
			System.out.println(Thread.currentThread().getName() + "\t读取数据" );
			Object result = map.get(key);
			System.out.println(Thread.currentThread().getName() + "\t读取完成" + result);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			readWriteLock.readLock().unlock();
		}
	}
}

/**
 * 1、多个线程同时读一个资源类，没有问题，所以，为了满足
 * 并发量，读取共享资源应该可以同步进行
 * 但是，如果有一个线程想要去写共享资源，就不应该再有其他线程
 * 对其资源进行读或写。
 * 2、总结
 * 读-读能共存
 * 读-写不能共存
 * 写-写不能共存
 */
public class ReadWriteLockDemo01 {
	public static void main(String[] args) {
		MyCache myCache = new MyCache();
		for (int i = 1; i <= 5; i++) {
			final int tempInt = i;
			new Thread(() -> {
				myCache.put(tempInt + "", tempInt + "");
			}, String.valueOf(i)).start();
		}
		for (int i = 1; i <= 5; i++) {
			final int tempInt = i;
			new Thread(() -> {
				myCache.get(tempInt + "");
			}, String.valueOf(i)).start();
		}
	}
}
